package wator.model;

/**
 * An instance of this class represents a 1-dimensional vector.
 * 
 * @see IntegerVector
 */
public class Integer1DVector extends IntegerVector {

	private int x;
	
	/**
	 * Sole constructor. Creates a 1-dimensional vector with given elements.
	 * 
	 * @param x the first element
	 */
	public Integer1DVector(int x) {
		this.x = x;
	}
	
	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#getDimension()
	 */
	@Override
	public int getDimension() {
		return 1;
	}
	
	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#mul(int)
	 */
	@Override
	public IntegerVector mul(int scalar) {
		return new Integer1DVector(x * scalar);
	}
	
	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#mul(double)
	 */
	@Override
	public IntegerVector mul(double scalar) {
		return new Integer1DVector((int) Math.round(((double) x) * scalar));
	}

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#div(int)
	 */
	@Override
	public IntegerVector div(int scalar) {
		return new Integer1DVector(x / scalar);
	}

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#mul(wator.model.IntegerVector)
	 */
	@Override
	public IntegerVector mul(IntegerVector v2) {
		return new Integer1DVector(x * ((Integer1DVector) v2).x);
	}

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#add(wator.model.IntegerVector)
	 */
	@Override
	public IntegerVector add(IntegerVector v2) {
		return new Integer1DVector(x + ((Integer1DVector) v2).x);
	}

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#sub(wator.model.IntegerVector)
	 */
	@Override
	public IntegerVector sub(IntegerVector v2) {
		return new Integer1DVector(x - ((Integer1DVector) v2).x);
	}

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#mod(wator.model.IntegerVector)
	 */
	@Override
	public IntegerVector mod(IntegerVector v2) {
		return new Integer1DVector(x % ((Integer1DVector) v2).x);
	}

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#generateRandomVectorInRange()
	 */
	@Override
	public IntegerVector generateRandomVectorInRange() {
		return new Integer1DVector((int) (Math.random() * x));
	}

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#max()
	 */
	@Override
	public int max() {
		return x;
	}

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#min()
	 */
	@Override
	public int min() {
		return x;
	}
	
	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#euclideanDistance2(IntegerVector)
	 */
	@Override
	public int euclideanDistance2(IntegerVector v2) {
		Integer1DVector o = (Integer1DVector) v2;
		return (o.x - x) * (o.x - x);
	}
	
	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#length2()
	 */
	@Override
	public int length2() {
		return x * x;
	}
	

	/* (non-Javadoc)
	 * @see wator.model.IntegerVectorreduce(IntegerVector)
	 */
	@Override
	public IntegerVector reduce(IntegerVector sizeVector) {
		Integer1DVector s = (Integer1DVector) sizeVector;
		int signX = x > 0 ? 1 : -1;
		return new Integer1DVector(
				signX * x <= (s.x / 2) ? x : (x - signX * s.x));
	}

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#vol()
	 */
	@Override
	public int vol() {
		return x;
	}
	
	
	/**
	 * Get the x-value (first dimension) of the vector.
	 * 
	 * @return the x value
	 */
	public int getX() {
		return x;
	}
	

	/* (non-Javadoc)
	 * @see wator.model.IntegerVector#compareTo(wator.model.IntegerVector)
	 */
	@Override
	public int compareTo(IntegerVector arg0) {
		if (equals(arg0)) {
			return 0;
		}
		return x - ((Integer1DVector) arg0).x;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Integer1DVector)) {
			return false;
		}
		return x == ((Integer1DVector) obj).x;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return 17 + x;
	}
}
